/**
 * Copyright (c) 2005-2010 springside.org.cn
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * 
 * $Id: JsonBinder.java 1216 2010-09-12 13:52:48Z calvinxiu $
 */
package com.alter.utils.encode;

import java.io.IOException;
import java.text.SimpleDateFormat;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion;

/**
 * Jackson的简单封装.
 * 
 * @author calvin
 */
public class JsonBinder {

    private static Logger logger = LoggerFactory.getLogger(JsonBinder.class);

    public static String jsonExtendConllection(Object obj) {
	try {
	    return buildNormalBinder().getMapper().writeValueAsString(obj);
	} catch (JsonProcessingException e) {
	    e.printStackTrace();
	    return "{}";
	}
    }

    private ObjectMapper mapper;

    public JsonBinder(Inclusion inclusion) {
	mapper = new ObjectMapper();
	// config
	mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
	mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
	mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
    }

    /**
     * 创建输出全部属性到Json字符串的Binder.
     */
    public static JsonBinder buildNormalBinder() {
	return new JsonBinder(Inclusion.ALWAYS);
    }

    /**
     * 创建只输出非空属性到Json字符串的Binder.
     */
    public static JsonBinder buildNonNullBinder() {
	return new JsonBinder(Inclusion.NON_NULL);
    }

    /**
     * 创建只输出初始值被改变的属性到Json字符串的Binder.
     */
    public static JsonBinder buildNonDefaultBinder() {
	return new JsonBinder(Inclusion.NON_DEFAULT);
    }

    /**
     * 如果JSON字符串为Null或"null"字符串,返回Null. 如果JSON字符串为"[]",返回空集合.
     * 
     * 如需读取集合如List/Map,且不是List<String>这种简单类型时使用如下语句: List<MyBean> beanList =
     * binder.getMapper().readValue(listString, new
     * TypeReference<List<MyBean>>() {});
     */
    public <T> T fromJson(String jsonString, Class<T> clazz) {
	if (StringUtils.isEmpty(jsonString)) {
	    return null;
	}

	try {
	    return mapper.readValue(jsonString, clazz);
	} catch (IOException e) {
	    logger.warn("parse json string error:" + jsonString, e);
	    return null;
	}
    }

    /**
     * 如果对象为Null,返回"null". 如果集合为空集合,返回"[]".
     */
    public String toJson(Object object) {

	try {
	    return mapper.writeValueAsString(object);
	} catch (IOException e) {
	    logger.warn("write to json string error:" + object, e);
	    return null;
	}
    }

    /**
     * 设置转换日期类型的format pattern,如果不设置默认打印Timestamp毫秒数.
     */
    public void setDateFormat(String pattern) {
	if (StringUtils.isNotBlank(pattern)) {
	    // DateFormat df = new SimpleDateFormat(pattern);
	    // mapper.getSerializationConfig().setDateFormat(df);
	    // mapper.getDeserializationConfig().setDateFormat(df);
	}
    }

    /**
     * 取出Mapper做进一步的设置或使用其他序列化API.
     */
    public ObjectMapper getMapper() {
	return mapper;
    }
}
